<?php
/** 
* 模型类文件(文章模块)
* 
* 文章的数据获取和视图标签的构建
* @author      sinalma  <sinalma@foxmail.com>
* @version     1.0 版本号
*/ 

namespace app\index\model;

use think\Model;
use think\Db;
use app\common\tools\Pagintor;
use think\Config;
use app\common\model\Search;

/** 
 * Class Article
 * 文章模型类 
 *
 * @package app\index\model
 * @method array getMetas(string $table) static 获取所有 分类/标签
 * @author      sinalma  <sinalma@foxmail.com>
 * @version     1.0 版本号
 */ 
class Article extends Model
{
    protected $table = 'sinblog_contents';
    private $htpURL = '';


    /**  
     * 获取指定文章id的上一篇和下一篇文章的信息(slug,title)
     * 
     * @access private 
     * @param mixed $cid 文章id
     * @return array 数组
     */     
    public function getBetween($cid){
        $sql = "SELECT created from sinblog_contents where cid='{$cid}'";
        $created = $this->query($sql);
        $sql = "SELECT slug,title from sinblog_contents where created>{$created[0]['created']} order by created limit 1";
        $last = $this->query($sql);
        $empty = array('title' => '没有了','slug'=>'' );
        $arts[] = count($last)==0?$empty:$last[0];
        $sql = "SELECT slug,title from sinblog_contents where created<'{$created[0]['created']}' order by created desc limit 1";
        $next = $this->query($sql);
        $arts[] = count($next)==0?$empty:$next[0];
        return $arts;
    }

    /**  
     * 文章搜索(关键字红色显示)
     * 实现原理:搜索顺序依次是,作者->标题->分类->标签->内容->时间
     * 
     * @access private 
     * @param mixed $type 分类或者标签('category'/'tag')
     * @return array 数组
     */     
    public function getSearch($pointStr,$page,$pagenum){
        $sql = "SELECT * from sinblog_contents where title like '%{$pointStr}%' or 'text' like '%{$pointStr}%' "."limit ".($page-1)*$pagenum.",".$pagenum;
        $res = $this->query($sql);
        if (!$res) {
          return $page == 1 ? "<h5>没有结果</h5>" : "<h5>没有更多结果</h5>" ;
        }

        for ($i=0; $i < count($res); $i++) { 
            $res[$i]['title'] = str_ireplace($pointStr, "<span style='color:red;'>{$pointStr}</span>",$res[$i]['title']);
            $startIdx = strpos($res[$i]['text'], $pointStr);
            $res[$i]['text'] = mb_substr($res[$i]['text'], $startIdx/3-20,150,"utf-8");
            $res[$i]['text'] = str_replace($pointStr, "<span style='color:red;'>{$pointStr}</span>",$res[$i]['text']);
        }
        $page = $page+1;
        return $this->getArtsHtml($res)."<a id='more-btn' href='javascript:showpage({$page})' style='background-color:white;color:black;font-size:12px;display:inline-block;width:100px;height:30px;text-align:center;line-height:30px;border:1px solid #334750;border-radius:5px;margin-bottom:20px;margin-left:40%;'>加载更多</a>";
    }


    /**  
     * 文章搜索
     * 实现原理:搜索顺序依次是,作者->标题->分类->标签->内容->时间
     * 
     * @access private 
     * @param mixed $type 分类或者标签('category'/'tag')
     * @return array 数组
     */ 
    public function getSearch_normal($pointStr,$page,$pagenum){
        $sql = "SELECT * from sinblog_contents where title like '%{$pointStr}%' "."limit ".($page-1)*$pagenum.",".$pagenum;
        // $sql = "SELECT * FROM sinblog_contentsWHERE title LIKE  '%swift%' LIMIT 0 , 5";
        $res = $this->query($sql);
        if($res){
          $page = $page+1;
          $seaobj = new Search();
          $res = $seaobj->getArticles($pointStr);
            return $this->getArtsHtml($res)."<a id='more-btn' href='javascript:showpage({$page})' style='background-color:white;color:black;font-size:12px;display:inline-block;width:100px;height:30px;text-align:center;line-height:30px;border:1px solid #334750;border-radius:5px;'>加载更多</a>";
        }
        return "<h5>没有结果</h5>";
    }

    /**  
     * 获取metas表分类或标签的名称(根据slug)
     * 
     * @access private 
     * @param mixed $type 分类或者标签('category'/'tag')
     * @return array 数组
     */ 
    public function getMetaName($slug){
        $res = $this->query("SELECT name from sinblog_metas where slug='{$slug}'");
        return  $res[0]['name'];
    }


    /**  
     * 获取所有的分类或者标签 
     * 
     * @access private 
     * @param mixed $type 分类或者标签('category'/'tag')
     * @return array 数组
     */  
    private function getMetas($type){
      $res = $this->query("SELECT mid,name,slug,count FROM  `sinblog_metas` WHERE type=:type",['type'=>$type]);
      return $res;
    }


    public function getCategories_opt(){
        // find all category from sinblog_metas             type -> mid
        // find all article id from sinblog_relationships   mid  -> cid
        // find article info from sinblog_contents          cid

        $sql = "SELECT * FROM `sinblog_contents` RIGHT JOIN (select cid from `sinblog_relationships` RIGHT JOIN (SELECT mid from `sinblog_metas` where type='category' ) as tab1 using(mid)) as tab2 USING(cid) where cid >= 0";
        $res = $this->query($sql);
        echo "<pre>";var_dump($res);echo "<pre>";

    }


    /**  
     * 获取所有分类,返回html(每块分类显示缩略文章标题)
     * 暂时每个分类文章少,缩略只显示5篇标题,需要继续测试
     * 
     * tips:核心代码等待重构抽取,和getMetaArticles
     *
     * @access public 
     * @return string 
     */  
    public function getCategories(){
        $html = "";

        // 获取所有分类
        $res = $this->getMetas("category");
        // 分类mid去文章表中获取显示在缩略页面的五篇文章title
        // $u = Config::get('HTP');
        // $u.=Config::get('URL');
        // 循环遍历每个分类
        for ($i=0;$i<count($res);$i++) { 
            // 如果当前分类下的文章数为零,则跳过
          if ($res[$i]['count'] <= 0){continue;}
$html .=  <<<eof
            <div class="widget">
              <div class="widget-title">
                <a href="{$this->htpURL}/category/{$res[$i]['slug']}.html">{$res[$i]['name']}</a>
                <span>文章:{$res[$i]['count']}</span>
              </div>
              <div class="widget-desc">
              </div>
              <ul class="widget-list">
eof;
        // 从relationships表中获取分类mid对应的文章
        $artCount = $res[$i]['count'] > 5 ? 5 : $res[$i]['count'];
               // 获取对应文章的所有cid
               $cids = $this->query("SELECT cid from sinblog_relationships where mid='{$res[$i]['mid']}' limit 0,{$artCount}");
               // 获取前五篇文章标题
               for ($k=0; $k < count($cids); $k++) { 
                  // 返回一个二维数组 
                  $art = $this->query("SELECT slug,cid,title from sinblog_contents where cid='{$cids[$k]['cid']}'");
$html .=  <<<eof
          
                <li><a href="{$this->htpURL}/article/{$art[0]['slug']}.html">{$art[0]['title']}</a></li>
eof;
                 }
$html .=  <<<eof
              </ul>
            </div>
eof;
      }
      return $html;
    }


    /**  
     * 获取所有标签,返回所有标签包含标签下文章数量的html
     * 
     * @access public 
     * @return string 
     */  
    public function getTags(){
        $html = "";
        // $res = $this->query("SELECT mid,name,slug,count FROM  `sinblog_metas` WHERE type =  'tag'");

        // 能否性能优化,数据小
        $res = $this->query("SELECT mid,name,slug,count FROM `sinblog_metas` INNER JOIN (SELECT mid FROM `sinblog_metas` WHERE type = 'tag') as mids USING(mid)");

        for ($i=0;$i<count($res);++$i){
          $href = $res[$i]['count'] >= 1 ? "{$this->htpURL}/tag/{$res[$i]['slug']}.html" : '#';

$html .=  <<<eof
           <li>
               <a href={$href}>{$res[$i]['name']}({$res[$i]['count']})</a>
           </li>
eof;
            }
        return $html;
    }



    /**  
     * 获取指定category/tag(分类/标签)下的文章,分页显示
     * 返回html字符串 
     * 
     * @access private 
     * @param mixed $slug 分类或者标签('category'/'tag')的slug
     * @param mixed $limitStr sql限制(limit)
     * @param mixed $PageNum 每页显示的文章数
     * @return string 
     */  
    public function getMetaArticles($slug,$limitStr,$PageNum){
        
        // 利用slug从typecho_metas表中获取分类/标签的mid
        // $res = $this->query("SELECT mid,count from sinblog_metas where slug='{$slug}'");
        // $mid = $res[0]['mid'];

        // 从relationships表中获取分类mid对应的文章
        // $artCount = $res[$i]['count'] > 5 ? 5 : $res[$i]['count'];

        // 获取对应文章的所有cid
         // $cidArrs = $this->query("SELECT cid from sinblog_relationships where mid='{$mid}' '{$limitStr}'");

        // 取出每个数组中的cid
        // $cids = array();
        // for ($i=0; $i < count($cidArrs); $i++) { 
        //     $cids[] = $cidArrs[$i]['cid'];
        // }
        // $cidsStr = join(',', $cids);

        // $sql = "SELECT * from sinblog_contents where cid in ($cidsStr)";
        // $arts = $this->query($sql);

        $arts = $this->query("
            SELECT * 
            FROM sinblog_contents 
            INNER JOIN (
            SELECT cid FROM sinblog_relationships WHERE mid = (
            SELECT mid FROM sinblog_metas WHERE slug='{$slug}' LIMIT 1
        ) {$limitStr}) AS mtab USING(cid)");

        // 构建html语句 
        $html = $this->getArtsHtml($arts);

        return $html;
    }


    /**  
     * 获取指定作者下的文章
     * 返回html字符串 
     * TODO:获取作者文章时使用id来获取,多一次操作数据库
     * 
     * @access private 
     * @param mixed $author 作者用户名
     * @param mixed $limitStr sql限制(limit)
     * @param mixed $PageNum 每页显示的文章数
     * @return string 
     */  
    public function getAuthorArticles($author,$limitStr,$pageNum){
        // $uid = $this->query("SELECT uid from sinblog_users where name='{$author}'");
        // $cidArr = $this->query("SELECT cid from sinblog_contents where authorId='{$uid[0]['uid']}'");
        // $cidArr = $this->query("SELECT cid FROM sinblog_contents WHERE  authorId=(SELECT uid FROM sinblog_users WHERE name='{$author}')");
        $arts = $this->query("SELECT * FROM sinblog_contents WHERE authorId = (SELECT uid FROM sinblog_users WHERE name='{$author}') {$limitStr}");
        // return $arts;
        // $cids = array();
        // for ($i=0; $i < count($cidArr); $i++) { 
        //      $cids[] = $cidArr[$i]['cid'];
        // }
        // $cidsStr = join(',', $cids); 
        // $sql = "SELECT * from sinblog_contents where cid in ($cidsStr) {$limitStr}";
        // $arts = $this->query($sql);

        // 构建html语句 
        $html = $this->getArtsHtml($arts);
        return $html;
    }


    /**  
     * 获取首页文章(页) 
     * 
     * @access public 
     * @param mixed $limitStr sql查询的限制,格式:limit 0,5
     * @param mixed $num 每页显示的文章数
     * @return array 数组
     */  
    public function getArticles($limitStr,$num){
        // 获取数据
        $sql = "SELECT * from sinblog_contents order by created desc ".$limitStr;
        $res = $this->query($sql);
        return $this->getArtsHtml($res);
    }
     
    /**  
     * 获取指定文章的详情数据
     * 
     * @access public 
     * @param mixed $cid 文章cid
     * @return array 数组
     */ 
    public function getArt($slug) {
        $res = $this->query("SELECT * from sinblog_contents where slug='{$slug}'");
        $art = $this->addInfo($res);
        return $art[0];
    }

    /**  
     * 获取文章页面html
     * 
     * @access private 
     * @param mixed $data 存储文章的数组
     * @return string
     */  
    private function getArtsHtml($data){
        
        // 缩略文章显示下，去除内容的所有markdown符号，紧凑显示
        for ($i=0; $i < count($data); $i++) { 
            $text = $data[$i]['text'];
            $data[$i]['text'] = str_replace(array('#','-','\r','\n','*','`'),'', $text);
        }

        $html = "";
        $blogs = $this->addInfo($data);
        for ($i=0;$i<count($blogs);++$i){
        $date = date('Y-m-d',$blogs[$i]["created"]);
$html .=  <<<eof
           <article class="post" itemscope="" itemtype="http://schema.org/BlogPosting">
        <h2 class="post-title" itemprop="name headline">
          <a itemtype="url" href="{$this->htpURL}/article/{$blogs[$i]['slug']}.html">
            {$blogs[$i]["title"]}
          </a>
        </h2>
        <ul class="post-meta">
          <li itemprop="author" itemscope="" itemtype="http://schema.org/Person">
            <i class="glyphicon glyphicon-user"></i>
            <a itemprop="name" href="{$this->htpURL}/author/{$blogs[$i]["author"]}.html" rel="author">{$blogs[$i]["author"]}</a>
          </li>
          <li>
            <i class="glyphicon glyphicon-book"></i>
            <a href="{$this->htpURL}/category/{$blogs[$i]["cslug"]}.html">{$blogs[$i]["categories"]}</a>
          </li>
          <li>
            <i class="
    glyphicon glyphicon-time"></i>
            <time datetime="2018-03-02T08:42:00+08:00" itemprop="datePublished">{$date}</time>
          </li>
          <li>阅读:({$blogs[$i]["order"]})</li>
        </ul>
        <div class="post-content" id="post-content" itemprop="articleBody">
          {$blogs[$i]['text']}
        </div>
      </article>
eof;
        }
        return $html;
    }


    /**  
     * 联合查询,获取需要显示在首页的缩略的所有文章信息
     * 在获取typecho_contents表的文章数据后,调用此方法传入数据
     * 补全信息包含:作者,阅读,时间,分类,[标签]
     * 涉及的表:typecho_metas,typecho_relationships
     * 
     * @access private 
     * @param mixed $data 文章数组
     * @return array 
     */  
    private function addInfo($data){
        $res = $data;
        // 需要添加分类信息,标签和作者到数组中
        for ($i=0;$i<count($res);$i++){
            $categories = "";
            $tags = array();
            // 获取每篇文章的id
            $artID = $res[$i]['cid'];
            // 从typecho_relationships表中获取对应文章id的分类id
            $relas = $this->query("SELECT mid from sinblog_relationships where cid='{$artID}'");
            // 如果没有值,给默认值

            $tagIdx = 0;
            // 从typecho_metas表中分别获取对应分类和标签名称
            for($j=0;$j<count($relas);$j++){
                $metas = $this->query("SELECT slug,type,name from sinblog_metas where mid={$relas[$j]['mid']}");
                if ($metas[0]['type'] == "category"){
                    $categories = $metas[0]['name'];
                    // 添加分类的mid到数组的每篇文章中
                    // ****************
                    // $res[$i]['slug'] = $metas[0]['slug'];
                    $res[$i]['cslug'] = $metas[0]['slug'];
                }else if ($metas[0]['type'] == "tag"){
                    $res[$i]['tags'][$tagIdx]['name'] = $metas[0]['name'];
                    $res[$i]['tags'][$tagIdx]['slug'] = $metas[0]['slug'];
                    $tagIdx += 1;
                }
            }

            // 从用户表中typecho_users中获取作者名
            $uid = $res[$i]['authorId'];
            $author = $this->query("SELECT name from sinblog_users where uid='{$uid}'");
            $res[$i]['author'] = $author[0]['name'];
            $res[$i]['categories'] = $categories;
        }
        return $res;
    }


    /**  
     * 获取指定作者下的所有文章数量
     * 
     * @access public 
     * @param mixed $author 作者用户名
     * @return int 
     */  
    public function getAuthorCount($author){
        // $uid = $this->query("SELECT uid from sinblog_users where name='{$author}'");
        // $res = $this->query("select count(*) as count from sinblog_contents where authorId='{$uid[0]['uid']}'" );
        $sql = "SELECT COUNT(*) AS count FROM sinblog_contents WHERE authorId=(SELECT uid FROM sinblog_users WHERE name='{$author}')";
        $res = $this->query($sql);
        return $res[0]['count'];
    }

    /**  
     * 获取某个 分类/tag 下的文章数 
     * 
     * @access public 
     * @param mixed $slug 指定分类的英文名
     * @return int 
     */  
    function getMetaCount($slug){
       $res = $this->query("SELECT count from sinblog_metas where slug='{$slug}'");
       return $res[0]['count'];
    }


    /**  
     * 获取总文章数 
     * 
     * @access public 
     * @return int 
     */  
    public function getCount(){
        $data = $this->query("SELECT count(*) as count from sinblog_contents");
        return $data[0]["count"];
    }
    
}